package com.qust.EnDecryption.handle;

import com.alibaba.fastjson2.JSONObject;
import com.qust.EnDecryption.common.Constant;
import com.qust.EnDecryption.common.MetaData;
import com.qust.EnDecryption.zookeeper.NeedChannel;
import com.qust.agreement.EnDecAgreement;
import com.qust.agreement.Enums.InstructionEnum;
import com.qust.agreement.Enums.SerializationEnum;
import com.qust.agreement.Message;
import com.qust.agreement.message.AlgorithmicResourceCatchUpMessage;
import com.qust.agreement.message.TransmissionAlgorithmMessage;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.Data;
import lombok.extern.log4j.Log4j2;

import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
@Log4j2
@ChannelHandler.Sharable
public class AlgorithmicResourceCatchUpHandle extends ChannelInboundHandlerAdapter implements NeedChannel {
    private Channel channel;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Message message = (Message) msg;
        if (message.getInstruction() == InstructionEnum.resourceCatchUp.getCode()){
            JSONObject context = (JSONObject)message.getContext();
            Message.AlgorithmicResourceCatchUpContext resourceCatchUpContext = context.to(Message.AlgorithmicResourceCatchUpContext.class);
            if (resourceCatchUpContext.getAddress().equals(Constant.nextNodeAddress)){
                for (int code : resourceCatchUpContext.getMissing()) {
                    MetaData.AlgorithmMetaData algorithmMetaData = Constant.META_DATA.getAlgorithmMetaDataMap().get(code);
                    try(InputStream inputStream = Files.newInputStream(Paths.get(algorithmMetaData.getJarPath()))){
                        byte[] jar = new byte[inputStream.available()];
                        int read = inputStream.read(jar);
                        log.debug("委托 下一层 进行传输");
                        super.channelRead(ctx,new Message(InstructionEnum.transmissionAlgorithm.getCode(), SerializationEnum.json.getCode(), JSONObject.from(new Message.AlgorithmTransmissionContext(
                                code, algorithmMetaData.getClassPath(), algorithmMetaData.getPublicKey(), algorithmMetaData.getPrivateKey(), jar,true
                        ))));
                    }
                }
                channel.writeAndFlush(
                        new AlgorithmicResourceCatchUpMessage(true)
                );
            }else {
                if (channel!=null){
                    channel.writeAndFlush(msg);
                }
            }
        }else {
            super.channelRead(ctx, msg);
        }
    }

    @Override
    public void need(Channel channel) {
        this.channel = channel;
    }
}
